package com.lej.core

import android.content.Context
import android.net.Uri
import android.util.Log
import com.qiniu.android.http.ResponseInfo
import com.qiniu.android.storage.Configuration
import com.qiniu.android.storage.UpProgressHandler
import com.qiniu.android.storage.UploadManager
import com.qiniu.android.storage.UploadOptions
import kotlinx.coroutines.suspendCancellableCoroutine
import org.json.JSONObject
import java.io.FileDescriptor
import java.io.FileInputStream
import java.text.SimpleDateFormat
import java.util.*
import kotlin.coroutines.resume


object QiNiuUtils {
    const val FACE = 0//人脸认证
    const val HEAD = 1//头像上传
    const val PUSH = 2//打卡
    const val STUDENT_CARD = 3//学生证上传
    const val CROP_HEAD = 4//裁剪的头像
    const val PUBLISH = 5//发布动态


    interface QiNiuProListener {
        fun qnProgress(key: String?, percent: Double)
    }

    private val sf = SimpleDateFormat("yyyyMMdd_HHmmssSS", Locale.CHINA)

    /**
     * 获取key,通过拼接uid和图片类型+时间戳确定唯一性
     * @param type 0:人脸认证, 1:头像上传 2:打卡认证 3.学生证上传
     * 1代表Android系统
     */
    fun getKeyOfImg(uid: String?, type: Int): String {
        return "${type}_1_${uid}_${sf.format(System.currentTimeMillis())}.jpg"
    }

    fun getKeyOfVideo(uid: String?, type: Int): String {
        return "${type}_1_${uid}_${sf.format(System.currentTimeMillis())}.mp4"
    }

    private var uploadManager: UploadManager? = null

    suspend fun upload(url: String, token: String, key: String?, listener: QiNiuProListener? = null)
            : String? {
        uploadManager ?: init()
        return suspendCancellableCoroutine { continuation ->
            uploadManager!!.put(
                url, key, token, { key: String?, info: ResponseInfo?, res: JSONObject? ->
                    //res包含hash、key等信息，具体字段取决于上传策略的设置
                    Log.i("qiniu", if (info?.isOK == true) "Upload Success" else "Upload Fail")
                    Log.i("qiniu", "$key,\r\n $info,\r\n $res")
                    continuation.resume(if (info?.isOK == true) key else null)
                }, UploadOptions(null, null, false,
                    { key, percent -> listener?.qnProgress(key, percent) }, null
                )
            )
        }
    }

    suspend fun upload(
        data: ByteArray,
        token: String,
        key: String?,
        handler: UpProgressHandler? = null
    ): String? {
        uploadManager ?: init()
        return suspendCancellableCoroutine { continuation ->
            uploadManager!!.put(
                data, key, token, { key: String?, info: ResponseInfo?, res: JSONObject? ->
                    //res包含hash、key等信息，具体字段取决于上传策略的设置
                    Log.i("qiniu", if (info?.isOK == true) "Upload Success" else "Upload Fail")
                    Log.i("qiniu", "$key,\r\n $info,\r\n $res")
                    continuation.resume(if (info?.isOK == true) key else null)
                }, UploadOptions(null, null, false, handler, null)
            )
        }
//        return uploadManager!!
//            .syncPut(data, key, token, UploadOptions(null, null, false, handler, null))
    }

    private fun init() {
        val config = Configuration.Builder()
            .connectTimeout(30)           // 链接超时。默认10秒
            .useHttps(true)
            .resumeUploadVersion(Configuration.RESUME_UPLOAD_VERSION_V2)
            .responseTimeout(60)          // 服务器响应超时。默认60秒
            .build()
        uploadManager = UploadManager(config)
        //配置3个线程数并发上传；不配置默认为3，只针对file.size>4M生效。线程数建议不超过5，
        // 上传速度主要取决于上行带宽，带宽很小的情况单线程和多线程没有区别
    }

    // 通过uri-path获取byte数据
    fun getByteFromUri(context: Context, path: String): ByteArray? {
        val uri = Uri.parse(path)
        try {
            val parcelFileDescriptor = context.contentResolver.openFileDescriptor(uri, "r")
            val fileDescriptor: FileDescriptor? = parcelFileDescriptor?.fileDescriptor
            if (fileDescriptor != null) {
                val inputStream = FileInputStream(fileDescriptor)
                return inputStream.readBytes()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }
}
